package com.motong.gongdan.service;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.mapper.LampRequestMapper;
import com.motong.gongdan.vo.H5Vo.common.GroupCountVo;
import com.motong.gongdan.vo.H5Vo.lamp.query.LampDropDownQuery;
import com.motong.gongdan.vo.H5Vo.lamp.query.LampListQuery;
import com.motong.gongdan.vo.H5Vo.lamp.vo.DashboardLampRequestVo;
import com.motong.gongdan.vo.H5Vo.lamp.vo.LampListVo;
import com.motong.gongdan.vo.system.common.vo.CheckBox;
import com.motong.gongdan.vo.system.lampRequest.query.LampTimingQuery;
import com.motong.gongdan.vo.system.lampRequest.vo.LampTimingTypeGroupVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LampRequestService extends ServiceImpl<LampRequestMapper, LampRequest> {

    @Resource
    private UserService userService;

    @Resource
    private LampRequestMapper lampRequestMapper;

    @Resource
    private LampRequestDetailService lampRequestDetailService;

    @Resource
    private LampRequestNoticeService lampRequestNoticeService;

    @Resource
    private LampTypeUserService lampTypeUserService;


    /**
     * 获取联络灯请求列表
     *
     * @param page  分页参数
     * @param param 请求参数
     * @return 联络灯请求列表
     */
    public Page<LampListVo> getList(Page<LampRequest> page, LampListQuery param) {
        Page<LampListVo> data = this.lampRequestMapper.getList(page, param);
        data.getRecords().forEach(i -> {
            if (Objects.nonNull(i.getCreateTime())) {
                long intervalSecond = DateUtil.between(i.getCreateTime(), Optional.ofNullable(i.getResponseTime()).orElse(new Date()), DateUnit.SECOND);
                BigDecimal interval = BigDecimal.valueOf(intervalSecond).divide(BigDecimal.valueOf(60L), 2, RoundingMode.UP);
                i.setResponseInterval(interval).setResponseIntervalCn(transferDateCn(i.getCreateTime(), i.getResponseTime()));
            }
            if (Objects.nonNull(i.getResponseTime())) {
                long intervalSecond = DateUtil.between(i.getResponseTime(), Optional.ofNullable(i.getFinishTime()).orElse(new Date()), DateUnit.SECOND);
                BigDecimal interval = BigDecimal.valueOf(intervalSecond).divide(BigDecimal.valueOf(60L), 2, RoundingMode.UP);
                i.setDealInterval(interval)
                        .setDealIntervalCn(transferDateCn(i.getResponseTime(), i.getFinishTime()));
            }
            if (Objects.nonNull(i.getFinishTime())) {
                long totalIntervalSecond = DateUtil.between(i.getCreateTime(), i.getFinishTime(), DateUnit.SECOND);
                BigDecimal interval = BigDecimal.valueOf(totalIntervalSecond).divide(BigDecimal.valueOf(60L), 2, RoundingMode.UP);
                BigDecimal totalIntervalHour = BigDecimal.valueOf(totalIntervalSecond).divide(BigDecimal.valueOf(3600L), 2, RoundingMode.UP);
                i.setTotalInterval(interval).setTotalIntervalHour(totalIntervalHour)
                        .setTotalIntervalCn(transferDateCn(i.getCreateTime(), i.getFinishTime()));
            }
            i.setLastIntervalCn(transferDateCn(i.getCreateTime(), i.getFinishTime()));
            if (Objects.nonNull(param.getId())) {
                List<LampRequestDetail> detailList = lampRequestDetailService.list(new LambdaQueryWrapper<LampRequestDetail>().eq(LampRequestDetail::getLampRequestId, i.getId()));
                List<Integer> userIds = detailList.stream().map(LampRequestDetail::getCreateUser).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(userIds)) {
                    Map<Integer, String> idNameMap = new HashMap<>(userIds.size());
                    userService.listByIds(userIds).forEach(d -> idNameMap.put(d.getId(), d.getName()));
                    detailList.forEach(d -> d.setCreateUserName(idNameMap.get(d.getCreateUser())));
                }
                i.setLampRequestDetails(detailList);
            }
        });
        return data;
    }

    /**
     * 联络灯请求下拉框
     *
     * @param query 下拉框请求参数
     */
    public List<CheckBox> dropDown(LampDropDownQuery query) {
        return this.lampRequestMapper.dropDown(query).stream().map(i -> new CheckBox().setRelationId(i.getType().toString()).setLabel(String.format("%s %s 发起了【%s】", DateUtil.formatDateTime(i.getCreateTime()), i.getCreateUserName(), i.getTypeName())).setValue(i.getId().toString())).collect(Collectors.toList());
    }


    /**
     * 联络灯类型联络灯请求id选择框
     *
     * @param query 下拉框请求参数
     */
    public List<CheckBox> typeRequestDropDown(LampDropDownQuery query) {
        return this.lampRequestMapper.dropDown(query).stream().map(i -> new CheckBox().setRelationId(i.getType().toString()).setLabel(i.getTypeName()).setValue(i.getId().toString())).collect(Collectors.toList());
    }


    /**
     * 根据设备和类型获取看板信息
     *
     * @param deviceIds 设备id
     * @param typeList  联络灯类型
     */
    public List<DashboardLampRequestVo> listByDeviceIdsAndType(List<Long> deviceIds, List<String> typeList) {
        List<DashboardLampRequestVo> data = this.lampRequestMapper.listByDeviceIdsAndType(deviceIds, typeList);
        data.forEach(i -> {
//            long durationHours = DateUtil.between(i.getCreateTime(), new Date(), DateUnit.HOUR);
//            String day = (durationHours / 24) + "天";
//            String hour = (durationHours % 24) + "时";
            i.setDurationName(transferDateCn(i.getCreateTime(), new Date()));
        });
        return data;
    }

    /**
     * 联络灯请求按类型数量统计
     *
     * @param groupId 分组
     */
    public List<GroupCountVo> getLampRequestTypeCount(String groupId) {
        return lampRequestMapper.getLampRequestTypeCount(groupId);
    }


    /**
     * 时间转换成天，小时,分钟,秒
     * 0不展示
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    private String transferDateCn(Date startTime, Date endTime) {
        return DateUtil.formatBetween(startTime, Optional.ofNullable(endTime).orElse(new Date()), BetweenFormatter.Level.SECOND);
    }

    public Page<LampTimingTypeGroupVo> durationGroupByType(Page<LampRequest> page, LampTimingQuery query) {
        Page<LampTimingTypeGroupVo> data = lampRequestMapper.durationGroupByType(page, query);
        data.getRecords().forEach(i -> {
            if (Objects.nonNull(i.getDurationHour())) {
                i.setDurationHour(i.getDurationHour().divide(BigDecimal.valueOf(3600), 2, RoundingMode.HALF_UP));
            }
        });
        return data;
    }

    public void sendDefaultLampRequestByLampType(DeviceInfo deviceInfo, LampType lampType) {
        String noticeText = "设备".concat(deviceInfo.getDeviceSn()).concat("发起了").concat(lampType.getName()).concat("联络灯呼叫,请及时处理");
        List<LampTypeUser> lampTypeUsers = lampTypeUserService.listByLampTypeId(lampType.getId());
        Date currentDate = new Date();
        if (!CollectionUtils.isEmpty(lampTypeUsers)) {
            String groupUserIds = lampTypeUsers.stream().map(i -> i.getUserId().toString()).collect(Collectors.joining(","));
            String groupUserNames = lampTypeUsers.stream().map(LampTypeUser::getUserName).collect(Collectors.joining(","));
            LampRequest lampRequest = new LampRequest().setType(lampType.getId()).setDeviceId(deviceInfo.getId()).setDealState(0)
                    .setDealUser(groupUserIds).setDealUserName(groupUserNames).setCreateTime(currentDate).setUpdateTime(currentDate);
            this.save(lampRequest);
            LampRequestDetail lampRequestDetail = new LampRequestDetail().setLampRequestId(lampRequest.getId())
                    .setContent("设备".concat("发起了联络灯请求。")).setCreateTime(currentDate).setUpdateTime(currentDate);
            lampRequestDetailService.save(lampRequestDetail);
            lampRequestNoticeService.noticeUserByLampUsers(noticeText, currentDate, lampRequest.getId(), lampTypeUsers);
        }

    }
}
